using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Sirenix.OdinInspector;
using Unity.VisualScripting;
using Unity.VisualScripting.FullSerializer;
using UnityEditor;
using UnityEngine;
using UnityEngine.WSA;

[Serializable]
public class Entity : MonoBehaviour
{
    public Dictionary<Type, BaseComponent> baseComponents = new Dictionary<Type, BaseComponent>();
    [HideInInspector]
    public bool IsInit;
    [ReadOnly]
    public ObjectPoolComponent objectPoolComponentReference; // 物体池组件引用

    protected void OnEnable()
    {
        if (GameEntry.Instance == null)
        {
            StartCoroutine(RegistarEntityNextFrame());
        }
        else
        {
            GameEntry.Instance.RegistarEntity(this);
            OnOpen();
        }
    }
    protected void OnDisable()
    {
        GameEntry.Instance.UnRegistarEntity(this);
        OnClose();
    }

    public virtual void OnAwake()
    {
        if (IsInit)
        {
            return;
        }
        IsInit = true;
        foreach (var basecomponent in baseComponents)
        {
            basecomponent.Value.OnAwake();
        }
    }

    public virtual void OnOpen()
    {
        foreach (var basecomponent in baseComponents)
        {
            basecomponent.Value.OnEnable();
        }
    }

    public virtual void OnStart()
    {

        foreach (var basecomponent in baseComponents)
        {
            basecomponent.Value.OnStart();
        }
    }

    public virtual void OnUpdate()
    {
        foreach (var basecomponent in baseComponents)
        {
            basecomponent.Value.OnUpdate();
        }
    }

    public virtual void OnClose()
    {
        foreach (var basecomponent in baseComponents)
        {
            basecomponent.Value.OnDisable();
        }

    }


    public virtual void OnDelete()
    {
        foreach (var basecomponent in baseComponents)
        {
            basecomponent.Value.OnDestroy();
        }
        baseComponents.Clear();
    }

    public virtual void ReStart()
    {
        
    }

    /// <summary>
    /// 增加一个组件
    /// </summary>
    /// <param name="baseComponent"></param>
    public void AddEcsComponent<T>(T t) where T : BaseComponent
    {
        Type type = typeof(T);
        baseComponents.Add(type, t);
        t.entity = this;

    }

    /// <summary>
    /// 获取一个组件，精确查找，速度非常快
    /// </summary>
    /// <param name="baseComponent"></param>
    /// <returns></returns>
    public BaseComponent GetEcsComponent(BaseComponent baseComponent)
    {
        baseComponents.TryGetValue(baseComponent.GetType(), out var component);
        if (component == null)
        {
            Debug.LogError("没有找到对应的组件: " + baseComponent.GetType().Name);
            return null;
        }
        return component;
    }

    // 查找组件现在是 O(1) 操作，非常快！精确查找！
    public T GetEcsComponent<T>() where T : BaseComponent
    {
        if (baseComponents.TryGetValue(typeof(T), out BaseComponent component))
        {
            return component as T;
        }
        return null;
    }

    /// <summary>
    /// 模糊查找所有的 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T[] GetEcsComponents<T>() where T : BaseComponent
    {
        var basecomponent = baseComponents.Where(_ => _.Value is T);
        if (basecomponent == null)
        {
            Debug.LogError("没有找到对应的组件: " + basecomponent.GetType().Name);
            return default(T[]);
        }
        var e = basecomponent.ToArray();
        T[] t = new T[e.Length];
        for (int i = 0; i < e.Length; i++)
        {
            t[i] = (T)e[i].Value;
        }
        return t;
    }

    public void RemoveEcsComponent(BaseComponent baseComponent)
    {
        if (baseComponents.TryGetValue(baseComponent.GetType(), out var component))
        {
            baseComponents.Remove(baseComponent.GetType());
        }
        else
        {
            Debug.LogError("没有找到要移除的组件: " + baseComponent.GetType().Name);
        }
    }

    //模糊查找当前实体中是否挂在某个组件或者他的子类组件
    public bool HasEcsComponent<T>() where T : BaseComponent
    {
        // 遍历字典中所有的值（即组件实例）
        foreach (var component in baseComponents.Values)
        {
            // 使用 'is' 关键字来检查继承关系
            // 'is' 关键字会正确地处理 "A is C" 的情况
            if (component is T)
            {
                return true; // 找到第一个匹配的就返回
            }
        }

        return false; // 遍历完也没找到
    }

    public void Recycle()
    {
        if (objectPoolComponentReference != null) {
            objectPoolComponentReference.Recycle(this.gameObject);
            
        }
    }

    private IEnumerator RegistarEntityNextFrame()
    {
        yield return null; // 等待一帧
        GameEntry.Instance.RegistarEntity(this);
        OnOpen();
    }


}
